﻿using System;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows.Controls;
using System.Xml.Linq;

namespace EveMarkets.UserControls
{
	/// <summary>
	/// Logique d'interaction pour UcMarketItem.xaml
	/// </summary>
	public partial class UcMarketItem : UserControl
	{
		#region Attributs
		private BackgroundWorker _bgwChercherInfo;
		private readonly bool _isRegion;
		private readonly int _idItem;
		private readonly int _idPosition;

		public bool IsOkJump { get; set; }
		public bool IsOkKill { get; set; }
		public bool IsOkMarket { get; set; }

		private const string PathWebBase = @"http://api.eve-central.com/api/marketstat?";
		private const string ObjetChoisi = @"typeid=";
		private const string RegionChoisie = @"&regionlimit=";
		private const string SystemChoisi = @"&usesystem="; 
		#endregion

		#region Constructeurs.
		public UcMarketItem(int numeroItem, bool uneRegion, int positionGeographique)
		{
			InitializeComponent();
			InitializeBackgroundWorker();

			_isRegion = uneRegion;
			_idItem = numeroItem;
			_idPosition = positionGeographique;

			this.IsEnabled = false;

			_bgwChercherInfo.RunWorkerAsync();
		}
		private void InitializeBackgroundWorker()
		{
			_bgwChercherInfo = new BackgroundWorker();
			_bgwChercherInfo.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);
			_bgwChercherInfo.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerCompleted);
		} 
		#endregion

		#region Events BackgroundWorker

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
		{
			// Get the BackgroundWorker that raised this event.
			BackgroundWorker worker = sender as BackgroundWorker;

			e.Result = RecupererInformation(_idItem, _idPosition, _isRegion);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
		{
			Tuple<decimal, decimal, decimal, decimal> tuple = e.Result as Tuple<decimal, decimal, decimal, decimal>;
			lblPriceMin.Content = tuple.Item1.ToString("N");
			lblPriceAvg.Content = tuple.Item2.ToString("N");
			lblPriceMax.Content = tuple.Item3.ToString("N");
			lblStock.Content = tuple.Item4.ToString("N");
			IsOkMarket = true;

			if(IsOkMarket && IsOkKill && IsOkJump)
				this.IsEnabled = true;
		}

		#endregion

		#region Méthodes private

		/// <summary>
		/// Méthode générale pour se connecter/prendre le flux XML et extraire les informations.
		/// </summary>
		/// <param name="idItem"></param>
		/// <param name="positionGeo"></param>
		/// <param name="isRegion"></param>
		/// <returns></returns>
		private Tuple<decimal, decimal,decimal,decimal> RecupererInformation(int idItem, int positionGeo, bool isRegion)
		{
			/*
			 * Dans cette méthode, je dois récupérer les informations de Eve-Central pour une région ou un système donnée, et un
			 * item donné.
			 * Exemples :
			 *  http://api.eve-central.com/api/marketstat?typeid=34&regionlimit=10000002
			 *	http://api.eve-central.com/api/marketstat?typeid=34&usesystem=30000142
			 */
			
			// Chercher sur Eve-CEntral le flux XML.
			XDocument xmlEveCentral = ChercherXmlSurEveCentral(idItem, positionGeo, isRegion);
			
			return ExtractXmlInformation(xmlEveCentral);
		}

		/// <summary>
		/// Extrait du flux XML de Eve-Central, les prix et volume.
		/// </summary>
		/// <param name="xmlEveCentral"></param>
		/// <returns>retourne prixMin, prixAvg, prixMax, volume</returns>
		private Tuple<decimal, decimal, decimal, decimal> ExtractXmlInformation(XDocument xmlEveCentral)
		{
			/*
			 * Le flux XML est de la forme :
			 * <!-- Automatically generated data from EVE-Central.com -->
				<!-- This is the new API :-) -->
				<evec_api version="2.0" method="marketstat_xml">
					<marketstat>
						<type id="34">
							<all>
								<volume>54761379198.00</volume>
								<avg>4.16</avg>
								<max>9.47</max>
								<min>0.69</min>
								<stddev>1.00</stddev>
								<median>4.30</median>
								<percentile>0.00</percentile>
							</all>
							<buy>
								<volume>36058517507.00</volume>
								<avg>3.91</avg>
								<max>4.42</max>
								<min>0.69</min>
								<stddev>0.76</stddev>
								<median>4.15</median>
								<percentile>4.39</percentile>
							</buy>
							<sell>
								<volume>22755932877.00</volume>
								<avg>4.84</avg>
								<max>9.47</max>
								<min>4.50</min>
								<stddev>0.86</stddev>
								<median>4.73</median>
								<percentile>4.51</percentile>
							</sell>
						</type>
					</marketstat>
				</evec_api>
			 */
			CultureInfo culture = new CultureInfo("en-US");
			decimal avg = Convert.ToDecimal(xmlEveCentral.Descendants("sell").Descendants("avg").Select(x => x.Value).First(), culture);
			decimal max = Convert.ToDecimal(xmlEveCentral.Descendants("sell").Descendants("max").Select(x => x.Value).First(), culture);
			decimal min = Convert.ToDecimal(xmlEveCentral.Descendants("sell").Descendants("min").Select(x => x.Value).First(), culture);
			decimal volume = Convert.ToDecimal(xmlEveCentral.Descendants("sell").Descendants("volume").Select(x => x.Value).First(), culture);

			return new Tuple<decimal, decimal, decimal, decimal>(min,avg,max,volume);
		}

		/// <summary>
		/// Va chercher sur EveCentral le flux XML.
		/// </summary>
		/// <param name="idItem"></param>
		/// <param name="positionGeo"></param>
		/// <param name="isRegion"></param>
		/// <returns></returns>
		private XDocument ChercherXmlSurEveCentral(int idItem, int positionGeo, bool isRegion)
		{
			// Construire l'URL du site.
			StringBuilder sb = new StringBuilder(5);
			sb.Append(PathWebBase)
				.Append(ObjetChoisi)
				.Append(idItem)
				.Append(isRegion ? RegionChoisie : SystemChoisi)
				.Append(positionGeo);

			// Création d'un objet WebClient (c'est lui qui permet de télécharger un fichier)
			WebClient wc = new WebClient();
			string downloadString = String.Empty;

			try
			{
				// Lancement du téléchargement
				// argument 1 : url du fichier source
				// argument 2 : l'emplacement ou enregistrer le fichier sur le disque dur
				downloadString = wc.DownloadString(sb.ToString());
			}
			catch (Exception e)
			{
				// Destruction de l'objet WebClient
				wc.Dispose();
			}
			finally
			{
				// Destruction de l'objet WebClient
				wc.Dispose();
			}

			return XDocument.Parse(downloadString); 
		}

		#endregion

		private void ClickOpenInformation(object sender, System.Windows.Input.MouseButtonEventArgs e)
		{
			if (lblSecurity.Content.ToString().Equals(String.Empty))
			{
				VueGeographique vue = new VueGeographique(_idItem, lblGeo.Content.ToString());
				vue.Show();
			}
		}

	}
}
